package com.travel.server.manager.impl.command.order.data;

import com.travel.common.CommonConstant;
import com.travel.common.util.CollectionUtil;
import com.travel.common.util.DateUtil;
import com.travel.server.manager.dto.request.order.data.QueryOrderChargeTargetRequest;
import com.travel.server.manager.dto.response.order.data.QueryOrderChargeTargetResponse;
import com.travel.server.manager.dto.response.order.data.QueryOrderChargeTargetResponse.DayTargetItem;
import com.travel.server.manager.dto.response.order.data.QueryOrderChargeTargetResponse.MonthTargetItem;
import com.travel.server.manager.dto.response.order.data.QueryOrderChargeTargetResponse.YearTargetItem;
import com.travel.server.manager.impl.command.AbstractCommand;
import com.travel.server.manager.impl.dal.data.UserTargetDal;
import com.travel.server.manager.model.UserOrderTarget;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: LiZhenhui
 * @Date: 2018\12\8 0008 15:41
 * @Desc:
 */
@Slf4j
@Component
public class QueryOrderChargeTargetCommand extends AbstractCommand<QueryOrderChargeTargetRequest, QueryOrderChargeTargetResponse> {

    @Autowired
    private UserTargetDal userTargetDal;

    private final static SimpleDateFormat monthSdf = new SimpleDateFormat("M月");

    private final static SimpleDateFormat daySdf = new SimpleDateFormat("d");

    @Override
    protected void checkInput(QueryOrderChargeTargetRequest request) {
        if(request.getYear() == null){
            throwInvalidParam();
        }
    }

    @Override
    public QueryOrderChargeTargetResponse handle(QueryOrderChargeTargetRequest request) {
        checkInput(request);

        List<Integer> yearList = Arrays.asList(request.getYear() - 1, request.getYear());
        List<YearTargetItem> yearTargetList = new ArrayList<>();
        Integer userId = request.getUserId();
        if(userId == null || userId == 0){
            userId = getUserInfo().getId();
        }
        for(Integer year : yearList) {
            YearTargetItem yearItem = new YearTargetItem();
            yearItem.setYear(year + "");
            Date startDate = DateUtil.getYearStart(year);
            Date endDate = DateUtil.getYearEnd(year);
            Map<String, String> monthMap = makeMap(userId, startDate, endDate, CommonConstant.DAY_TYPE_MONTH);
            Map<String, String> dayMap = makeMap(userId, startDate, endDate, CommonConstant.DAY_TYPE_DAY);

            Calendar startMonth = Calendar.getInstance();
            startMonth.setTime(startDate);
            List<MonthTargetItem> monthList = new ArrayList<>();
            while (startMonth.getTime().before(endDate) || startMonth.getTime().equals(endDate)) {
                MonthTargetItem monthItem = new MonthTargetItem();
                monthItem.setTarget(monthMap.get(getMpaKey(startMonth.getTime())));
                monthItem.setMonth(monthSdf.format(startMonth.getTime()));
                List<DayTargetItem> dayList = new ArrayList<>();

                Calendar startDay = getMonthFirstDay(startMonth);
                Calendar endDay = getMonthLastDay(startMonth);
                while (startDay.getTime().before(endDay.getTime()) || startDay.getTime().equals(endDay.getTime())) {
                    DayTargetItem dayItem = new DayTargetItem();
                    dayItem.setTarget(dayMap.get(getMpaKey(startDay.getTime())));
                    dayItem.setDay(daySdf.format(startDay.getTime()));
                    dayList.add(dayItem);
                    startDay.add(Calendar.DAY_OF_MONTH, 1);
                }

                monthItem.setDayTargetList(dayList);
                monthList.add(monthItem);

                startMonth.add(Calendar.MONTH, 1);
            }
            yearItem.setMonthTargetList(monthList);
            yearTargetList.add(yearItem);
        }

        QueryOrderChargeTargetResponse response = new QueryOrderChargeTargetResponse();
        response.setYearTargetList(yearTargetList);

        return response;
    }

    public Map<String, String> makeMap(Integer userId, Date startDate, Date endDate, Integer dateType){
        List<UserOrderTarget> list = userTargetDal.selectTargetList(userId, startDate, endDate, dateType);
        Map<String, String> map = new HashMap<>();
        if(!CollectionUtil.isEmpty(list)){
            for(UserOrderTarget target : list){
                map.put(getMpaKey(target.getTargetDate()), target.getTargetNum());
            }
        }
        return map;
    }

    private String getMpaKey(Date date){
        return DateUtil.YYYYMMDD.format(date);
    }

    private Calendar getMonthFirstDay(Calendar cal){
        Calendar calendar = getNewCalendar(cal);
        //获取某月最小天数
        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最小天数
        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
        return calendar;
    }

    private Calendar getMonthLastDay(Calendar cal){
        Calendar calendar = getNewCalendar(cal);
        //获取某月最大天数
        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        return calendar;
    }

    private Calendar getNewCalendar(Calendar cal){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, cal.get(Calendar.YEAR));
        calendar.set(Calendar.MONTH, cal.get(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, cal.get(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, cal.get(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, cal.get(Calendar.MILLISECOND));
        return calendar;
    }
}
